package org.smile.service;

import org.smile.beans.converter.BeanException;
import org.smile.commons.SmileRunException;
import org.smile.file.ClassPathFileScanner;
import org.smile.reflect.ClassTypeUtils;
import org.smile.util.Properties;
import org.smile.util.SysUtils;

import java.io.IOException;
import java.io.InputStream;

public class ServiceScanner {
    /**
     * 模板适配器配置文件名称
     */
    private String configExtension = "service";
    /**
     * 模板适配器配置文件目录
     */
    private String configDir = "META-INF/service/";

    public ServiceScanner(String dir, String extension) {
        this.configDir = dir;
        this.configExtension = extension;
    }

    public ServiceScanner(String dir) {
        this.configDir = dir;
    }

    public void scan(){
        this.scan(new DefaultServiceContext());
    }

    public void scan(ServiceContext serviceContext) {
        ClassPathFileScanner scanner = new ClassPathFileScanner(configDir, new ClassPathFileScanner.BaseVisitor() {
            @Override
            public boolean visit(String fileName, InputStream is) throws IOException {
                Properties p = new Properties();
                p.load(is);
                for (Object s : p.keySet()) {
                    try {
                        Class clazz = Class.forName(String.valueOf(s));
                        if (Service.class.isAssignableFrom(clazz)) {
                            Service service = (Service) ClassTypeUtils.newInstance(clazz);
                            service.onload();
                            serviceContext.onServiceRegister(service);
                            service.afterLoad(serviceContext);
                        }
                    } catch (ClassNotFoundException e) {
                        SysUtils.log(e);
                    } catch (BeanException e) {
                        throw new RuntimeException(e);
                    }
                }
                return false;
            }

            @Override
            public boolean accept(String fileName, String protocol) {
                return fileName.endsWith(configExtension);
            }
        });
        try {
            scanner.scanning();
            serviceContext.onScanEnd(this);
        } catch (IOException e) {
            throw new SmileRunException(e);
        }
    }
}
